<!--
 * @Author: your name
 * @Date: 2021-07-17 14:33:53
 * @LastEditTime: 2021-07-18 16:14:48
 * @Description: 
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>封装集合</title>
</head>

<body>
    <p>1. 无序的</p>
    <p>2. 不允许重复</p>
    <script>
        function Set() {
            // 属性
            this.items = {}

            // 方法
            Set.prototype.add = function (value) {
                // 判断当前集合中是否已经包含了该元素
                if (this.has(value)) {
                    return false
                }
                // 将元素添加到集合中
                this.items[value] = value
                return true
            }

            Set.prototype.has = function (value) {
                return this.items.hasOwnProperty(value)
            }

            Set.prototype.remove = function(value) {
                // 1. 判断集合是否包含该元素
                if (!this.has(value)) {
                    return false
                }

                // 2. 将元素从属性删除
                Reflect.deleteProperty(this.items, value)
                return true
            }

            Set.prototype.clear = function() {
                this.items = {}
                return true
            }

            Set.prototype.size = function() {
                return Object.keys(this.items).length
            }

            Set.prototype.values = function() {
                return Object.keys(this.items)
            }

            // 集合间的操作
            // 集合间并集操作
            Set.prototype.union = function(otherSet) {
                // this 已经是一个集合对象A
                // otherSet 集合B
                // 1. 创建新的集合
                var unionSet = new Set()

                // 2. 将A集合中所有的元素添加到新集合中
                var values = this.values()
                for (var i = 0; i < this.size(); i ++) {
                    unionSet.add(values[i])
                }

                // 3. 取出B集合中的元素，判断是否需要添加到集合
                values = otherSet.values()
                for (var i = 0; i < values.length; i ++) {
                    unionSet.add(values[i])
                }

                return unionSet
            }
            
            // 集合交集操作
            Set.prototype.intersection = function(otherSet) {
                // this: 集合A
                // otherSer: 集合B
                
                // 1. 创建新的集合
                var intersection = new Set()

                // 2. 从A集合取出一个个元素，判断是否同时存在于集合B
                var values = this.values()
                for (var i = 0; i < values.length; i++) {
                    var item = values[i]
                    if (otherSet.has(item)) {
                        intersection.add(item)
                    }
                }
                return intersection
            }
       
            // 集合差集操作[值在A集合中，不存在B集合中]
            Set.prototype.difference = function(otherSet) {
                var difference = new Set()

                var values = this.values()
                for (var i = 0; i < values.length; i++ ) {
                    var item = values[i]
                    if (!otherSet.has(item)) {
                        difference.add(item)
                    }
                }
                return difference
            }
            
            // 集合子集操作
            Set.prototype.subset = function(otherSet) {
                var values = this.values()

                for (var i = 0; i < values.length; i++) {
                    var item = values[i]
                    if (!otherSet.has[item]) {
                        return false
                    }
                }
                return false
            }
        }

        var setA = new Set()
        setA.add(0)
        setA.add('a')
        setA.add('b')
        setA.add('ss')
        
        var setB = new Set()
        setB.add('1')
        setB.add('2')
        setB.add('3')
        setB.add('ss')
        setB.add('ddd')

        var unionSet = setA.subset(setB)
        console.log(unionSet)
    </script>
</body>

</html>